package org.jsola.hr.service.excel;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.fastjson.JSON;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
import org.jsola.common.BeanKit;
import org.jsola.hr.common.RegUtils;
import org.jsola.hr.service.IMissionCenterService;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author lyh
 */

@Slf4j
@Data
@EqualsAndHashCode(callSuper = true)
public class MissionCenterImportListener extends BaseAnalysisEventListener<Map<Integer, String>> {


    /**
     * 表头
     */
    private Map<Integer, String> allHeadMap;

    /**
     * List最大盛装数据条数
     */
    private static final Integer MAX_COUNT = 2000;

    /**
     * 解析Excel结果
     */
    private List<Map<Integer, String>> parseList = new ArrayList<>();

    /**
     * 姓名
     */
    private static final String NAME = "姓名";

    /**
     * 身份证号
     */
    private static final String ID_CARD = "身份证号";

    /**
     * 表头是否正确
     */
    private Boolean checkHead = true;

    /**
     * 数据长度是否正确
     */
    private Boolean checkDateSize = true;

    /**
     * 数据长度是否正确
     */
    private List<String> dateSizeWrongsIndex = new ArrayList<>();

    /**
     * 错误描述:"姓名为空"
     */
    private static final String NAME_EMPTY = "姓名为空; ";

    /**
     * 错误描述:"身份证号为空"
     */
    private static final String ID_CARD_EMPTY = "身份证号为空; ";

    /**
     * 错误描述:"身份证号重复"
     */
    private static final String ID_CARD_REPEAT = "身份证号重复; ";

    /**
     * 错误描述:"身份证号格式错误"
     */
    private static final String ID_CARD_FORMAT_WRONG = "身份证号格式错误; ";

    /**
     * 姓名标识
     */
    private static final String NAME_FLAG = "name";

    /**
     * 身份证号标识
     */
    private static final String ID_CARD_FLAG = "idCard";

    /**
     * 错误数据的盛装容器  "<错误行号,<姓名/身份证号,错误描述>>"
     */
    private Map<Integer, Map<String, String>> wrongsDateMap = new HashMap<>(16);

    /**
     * 校验身份证号需要的容器  <身份证号,行号>
     */
    private Map<String, Integer> idCardMap = new HashMap<>(256);

    /**
     * 重复的表头
     */
    private List<String> repeatsHead = new ArrayList<>();

    @Override
    public void saveData() {
        IMissionCenterService missionCenterService = BeanKit.getBean(IMissionCenterService.class);
    }


    @Override
    public void invoke(Map<Integer, String> data, AnalysisContext context) {
        // 获取行的索引
        log.info("解析到一条数据:{}", JSON.toJSONString(data));
        if (parseOnly) {
            // 这里的index是从1开始的
            int wrongsIndex = context.readRowHolder().getRowIndex();
            // 校验本条数据是否错误,现阶段只校验前两列:"姓名","身份证号"
            boolean dataWrongs = false;
            if (data.size() > allHeadMap.size()) {
                // 如果数据行比表头都多,标记为此次解析有误,并记下行号
                checkDateSize = false;
                // 实际Excel第一行是表头,第二行才是数据,所以这里需要index + 1
                dateSizeWrongsIndex.add(Integer.toString(wrongsIndex + 1));
            }
            String name = data.get(0);
            String idCard = data.get(1);
            Map<String, String> wrongsDescription = new HashMap<>(8);
            if (idCardMap.containsKey(idCard)) {
                dataWrongs = true;
                Integer firstRepeatIndex = idCardMap.get(idCard);
                // 如果已经有过错误了
                if (wrongsDateMap.containsKey(firstRepeatIndex)) {
                    Map<String, String> firstRepeatDescriptionMap = wrongsDateMap.get(firstRepeatIndex);
                    // 判断错误里面有没有身份证错误
                    if (firstRepeatDescriptionMap.containsKey(ID_CARD_FLAG)) {
                        String idCardFormat = firstRepeatDescriptionMap.get(ID_CARD_FLAG);
                        firstRepeatDescriptionMap.put(ID_CARD_FLAG, idCardFormat + ID_CARD_REPEAT);
                    } else {
                        firstRepeatDescriptionMap.put(ID_CARD_FLAG, ID_CARD_REPEAT);
                    }
                    wrongsDateMap.put(firstRepeatIndex, firstRepeatDescriptionMap);
                } else {
                    Map<String, String> firstRepeatWrongs = new HashMap<>(8);
                    firstRepeatWrongs.put(ID_CARD_FLAG, ID_CARD_REPEAT);
                    wrongsDateMap.put(firstRepeatIndex, firstRepeatWrongs);
                }
                wrongsDescription.put(ID_CARD_FLAG, ID_CARD_REPEAT);
            } else {
                // 因为这里要对应List里面的数据所以index - 1
                idCardMap.put(idCard, wrongsIndex - 1);
            }

            if (StringUtils.isEmpty(name)) {
                wrongsDescription.put(NAME_FLAG, NAME_EMPTY);
                dataWrongs = true;
            }
            if (StringUtils.isEmpty(idCard)) {
                wrongsDescription.put(ID_CARD_FLAG, ID_CARD_EMPTY);
                dataWrongs = true;
            } else {
                if (ObjectUtils.isEmpty(RegUtils.cardType(idCard))) {
                    if (wrongsDescription.containsKey(ID_CARD_FLAG)) {
                        wrongsDescription.put(ID_CARD_FLAG, wrongsDescription.get(ID_CARD_FLAG) + ID_CARD_FORMAT_WRONG);
                    } else {
                        wrongsDescription.put(ID_CARD_FLAG, ID_CARD_FORMAT_WRONG);
                    }
                    dataWrongs = true;
                }
            }
            if (dataWrongs) {
                // 因为这里的index需要与parseList里面的index对应
                // List的index是从0开始,所以这里wrongsIndex - 1
                wrongsDateMap.put(wrongsIndex - 1, wrongsDescription);
            }
            parseList.add(data);
        } else {
            dataList.add(data);
            if (dataList.size() >= MAX_COUNT) {
                // 入库
                saveData();
                // 存储完成清理 list
                dataList.clear();
            }
        }
    }

    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        List<String> checkRepeats = new ArrayList<>();
        String name = headMap.get(0);
        String idCard = headMap.get(1);
        if (!NAME.equals(name) || !ID_CARD.equals(idCard)) {
            checkHead = false;
        }
        for (Integer integer : headMap.keySet()) {
            String head = headMap.get(integer);
            if(checkRepeats.contains(head)){
                repeatsHead.add(head);
                continue;
            }
            checkRepeats.add(head);
        }
        allHeadMap = headMap;
    }
}
